package com.zjdiepu.www.biz.file;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.zjdiepu.www.base.core.BaseException;
import com.zjdiepu.www.base.enums.type.ResultFlagType;
import com.zjdiepu.www.ibiz.file.IZipService;

/**
 * 项目名称：dpqc-parent-manager-file <br/>
 * 类名称：ZipSerivceImpl <br/>
 * 类描述：文件解压缩 <br/>
 * 创建人：xiongxiaotun <br/>
 * 创建时间：2017年4月14日 上午11:19:13 <br/>
 * 修改人：xiongxiaotun <br/>
 * 修改时间：2017年4月14日 上午11:19:13 <br/>
 * 修改备注： <br/>
 * 
 * @version V1.0 <br/>
 */
@Service
public class ZipSerivceImpl implements IZipService {
	private Logger logger = LoggerFactory.getLogger(getClass());

	private static final int BUFFER = 8192;


	/**
	 * 压缩单个或多文件方法
	 * 
	 * @param zipPath
	 *            压缩后的文件路径
	 * @param srcPathName
	 *            要压缩的文件路径 参数srcPathName也可以定义成数组形式，需调用方把参数封装到数组中传过来即可
	 */
	public void pack(String zipPath, String... srcPathName) {
		// 压缩后的文件对象
		File zipFile = new File(zipPath);
		File folder = zipFile.getParentFile();
		if(!folder.exists()) {
			folder.mkdirs();
		}
		// 创建写出流操作
		try (FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
				CheckedOutputStream cos = new CheckedOutputStream(
						fileOutputStream, new CRC32());
				ZipOutputStream out = new ZipOutputStream(cos);) {
			for (String srcPath : srcPathName) {
				// 创建需要压缩的文件对象
				File file = new File(srcPath);
				if (!file.exists()) {
					continue;
				}
				String basedir = "";
				pack(file, out, basedir);
			}
		} catch (IOException e) {
			logger.error("pack files IOException.zipPath is {}, srcPathName is {}, exception is {}.",
					zipPath, srcPathName, e);
			throw new BaseException(ResultFlagType.FILE_PACK_EXCEPTION
					.getCode().toString(),
					ResultFlagType.FILE_PACK_EXCEPTION.getValue());
		}

	}

	public void pack(File file, ZipOutputStream out, String basedir)
			throws IOException {
		if (file.isDirectory()) {
			basedir += file.getName() + File.separator;
			packDirectory(file, out, basedir);
		} else {
			packFile(file, out, basedir);
		}
	}

	public void packDirectory(File dir, ZipOutputStream out, String basedir)
			throws IOException {
		if (!dir.exists()) {
			return;
		}
		File[] files = dir.listFiles();
		for (int i = 0; i < files.length; i++) {
			/* 递归 */
			pack(files[i], out, basedir);
		}
	}

	public void packFile(File file, ZipOutputStream out, String basedir)
			throws IOException {
		if (!file.exists()) {
			return;
		}
		try (BufferedInputStream bis = new BufferedInputStream(
				new FileInputStream(file));) {
			// 创建Zip实体，并添加进压缩包
			ZipEntry entry = new ZipEntry(basedir + file.getName());
			out.putNextEntry(entry);
			// 读取待压缩的文件并写进压缩包里
			int count;
			byte data[] = new byte[BUFFER];
			while ((count = bis.read(data, 0, BUFFER)) != -1) {
				out.write(data, 0, count);
			}
		}
	}

	@Override
	public void dePack(String sourceFile, String destDir) {
		try{
		 //创建需要解压缩的文件对象  
        File file = new File(sourceFile);  
        if (!file.exists()){  
        	throw new BaseException(ResultFlagType.FILE_NOT_FOUND
					.getCode().toString(),
					ResultFlagType.FILE_NOT_FOUND.getValue());
        }  
        //创建解压缩的文件目录对象  
        File destDiretory  = new File(destDir);  
        if(!destDiretory.exists()){  
            destDiretory.mkdirs();  
        }  
        /* 
         * 保证文件夹路径最后是"/"或者"\" 
         * charAt()返回指定索引位置的char值 
         */  
        char lastChar = destDir.charAt(destDir.length()-1);  
        if(lastChar!='/' && lastChar!='\\'){  
            //在最后加上分隔符  
            destDir += File.separator;  
        }  
        dePackAction(sourceFile, destDir);  
		}catch(IOException e){
			logger.error("pack files IOException.sourceFile is {}, destDir is {}, exception is {}.",
					sourceFile, destDir, e);
			throw new BaseException(ResultFlagType.FILE_UNPACK_EXCEPTION
					.getCode().toString(),
					ResultFlagType.FILE_UNPACK_EXCEPTION.getValue());
		}
		
	}

	@Override
	public void dePackAction(String sourceZip, String destDir)
			throws IOException {
		 Project p = new Project();  
         Expand e = new Expand();  
         e.setProject(p);  
         e.setSrc(new File(sourceZip));  
         e.setOverwrite(false);  
         e.setDest(new File(destDir));  
         e.execute();  
	}
}
